package com.shiny.concurrency4java.atomic;

import com.shiny.concurrency4java.annoations.ThreadSafe;
import com.shiny.concurrency4java.util.Constant;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.LongAdder;

@ThreadSafe
@Slf4j
public class AtomicLongAdder {

    private LongAdder longAdder = new LongAdder();

    private void safeCount(){
        longAdder.increment();
    }

    public static void main(String[] args) throws Exception{
        final AtomicLongAdder cas = new AtomicLongAdder();
        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore = new Semaphore(Constant.threadTotal);
        final CountDownLatch countDownLatch = new CountDownLatch(Constant.clientTotal);
        long start = System.currentTimeMillis();
        for( int i = 0; i < Constant.clientTotal; i++ ){
            executorService.execute(()->{
                try {
                    semaphore.acquire();
                    cas.safeCount();
                    semaphore.release();

                }catch (Exception e) {
                    e.printStackTrace();
                }
                countDownLatch.countDown();

            });
        }
        countDownLatch.await();
        executorService.shutdown();
        log.info("cas atomicI:{}",cas.longAdder.toString());
        log.info("intervalTime:{}",System.currentTimeMillis() - start);
        return;
    }


}
